''' Unit of measure (UOM) tests
'''
import scopt.test.common
from scopt.mpu.business.settings.handlers import uom


class UomCreate(scopt.test.common.ScoptTest):
    ''' UOM creation tests
    MPU should:

    1. test_uom_create_unique
        allow to create UOM
    2. test_uom_create_duplicate
        disallow to create UOM with same name
    3. test_uom_create_read
        create UOM and retrieve it with returned UOM entry id
    '''
    def test_uom_create_unique(self):
        # SomeNewUom is not part of demo data
        request = self.request(uom.create)
        request['reqd'] = {'name': 'SomeNewUom'}

        response = self.send_request(request)
        response_status = response['resh']['status']

        self.assertEqual(response_status, 'OK')

    def test_uom_create_duplicate(self):
        # kg is part of demo data
        request = self.request(uom.create)
        request['reqd'] = {'name': 'kg'}

        response = self.send_request(request,
                                     pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.violation.unique_key')

    def test_uom_create_read(self):
        # SomeNewUom is not part of demo data
        uom_to_create = 'SomeNewUom'
        create_request = self.request(uom.create)
        create_request['reqd'] = {'name': uom_to_create}

        create_response = self.send_request(create_request)

        select_request = self.request(uom.select)
        select_request['reqd'] = {'id': create_response['resd']['id']}

        select_response = self.send_request(select_request)
        response_status = select_response['resh']['status']
        select_resd = select_response['resd']
        uom_name_created = select_resd[0]['name']

        self.assertEqual(response_status, 'OK')
        self.assertEqual(len(select_resd), 1)
        self.assertEqual(uom_name_created, uom_to_create)


class UomSelect(scopt.test.common.ScoptTest):
    ''' UOM select tests
    MPU should:

    1. test_uom_select_one
        select one UOM by uom_id
    2. test_uom_select_all
        select all UOMs by not providing id
    3. test_uom_select_none
        select none UOM by providing id of non existent record
    '''
    def test_uom_select_one(self):
        # row with id 1 is part of demo data
        request = self.request(uom.select)
        request['reqd'] = {'id': 1}

        response = self.send_request(request)
        response_status = response['resh']['status']
        data = response['resd']

        self.assertEqual(response_status, 'OK')
        self.assertEqual(len(data), 1)

    def test_uom_select_all(self):
        # there are 4 rows in uom demo data
        request = self.request(uom.select)
        request['reqd'] = {}

        response = self.send_request(request)
        response_status = response['resh']['status']
        data = response['resd']

        self.assertEqual(response_status, 'OK')
        self.assertEqual(len(data), 4)

    def test_uom_select_none(self):
        # row with id of 200 is not present in demo data
        request = self.request(uom.select)
        request['reqd'] = {'id': 200}

        response = self.send_request(request)
        response_status = response['resh']['status']
        data = response['resd']

        self.assertEqual(response_status, 'OK')
        self.assertEqual(len(data), 0)


class UomUpdate(scopt.test.common.ScoptTest):
    ''' UOM update tests
    MPU should:

    1. test_uom_update_new_name
        allow update UOM to other unique name
    2. test_uom_update_duplicate_name
        disallow update UOM to name which is not unique
    3. test_uom_update_invalid_id
        disallow update UOM with invalid id
    4. test_uom_update_missing_id
        disallow update UOM with id is missing
    5. test_uom_update_read
        update and read UOM by its ID
    '''
    def test_uom_update_new_name(self):
        # row with id 1(kg) is part of demo data
        request = self.request(uom.update)
        request['reqd'] = {'id': 1,
                           'name': 'SomeNewUom'}

        response = self.send_request(request)
        response_status = response['resh']['status']

        self.assertEqual(response_status, 'OK')

    def test_uom_update_duplicate_name(self):
        # row with name 'm' is part of demo data
        request = self.request(uom.update)
        request['reqd'] = {'id': 1,
                           'name': 'm'}

        response = self.send_request(request,
                                     pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.violation.unique_key')

    def test_uom_update_invalid_id(self):
        # rows with id over 100 are not part of demo data
        request = self.request(uom.update)
        request['reqd'] = {'id': 101,
                           'name': 'm'}

        response = self.send_request(request,
                                     pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_invalid')

    def test_uom_update_missing_id(self):
        request = self.request(uom.update)
        request['reqd'] = {'name': 'm'}

        response = self.send_request(request,
                                     pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_none')

    def test_uom_update_read(self):
        # SomeNewUom is not part of demo data
        uom_id_to_update = 1
        uom_name_to_update = 'SomeNewUom'
        update_request = self.request(uom.update)
        update_request['reqd'] = {'id': uom_id_to_update,
                                  'name': uom_name_to_update}

        self.send_request(update_request)
        select_request = self.request(uom.select)
        select_request['reqd'] = {'id': uom_id_to_update}

        select_response = self.send_request(select_request)
        response_status = select_response['resh']['status']
        select_resd = select_response['resd']
        uom_name_updated = select_resd[0]['name']

        self.assertEqual(response_status, 'OK')
        self.assertEqual(len(select_resd), 1)
        self.assertEqual(uom_name_updated, uom_name_to_update)
